libxl: vncviewer: make autopass work properly
authorIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 4 Feb 2011 18:47:39 +0000 (18:47 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 4 Feb 2011 18:47:39 +0000 (18:47 +0000)
The file we write the vnc password to must be rewound back to the
beginning, or the vnc viewer will simply get EOF.

When the syscalls for communicating the password to the vnc client
fail, bomb out with an error messsage rather than blundering on (and
probably producing a spurious password prompt).

Following this patch, xl vncviewer --autopass works, provided the qemu
patch for writing the password to xenstore has also been applied.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxl/libxl.c

index c6723385a5f626bfc746d028513b650b99d2e4b9..1554d8824ac2c5f7f3c5366c8d8f7ce3bb4c8801 100644 (file)
@@ -827,25 +827,38 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass)
     if ( vnc_pass ) {
         char tmpname[] = "/tmp/vncautopass.XXXXXX";
         autopass_fd = mkstemp(tmpname);
-        if ( autopass_fd < 0 )
-            goto skip_autopass;
+        if ( autopass_fd < 0 ) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                             "mkstemp %s failed", tmpname);
+            goto x_fail;
+        }
 
-        if ( unlink(tmpname) )
+        if ( unlink(tmpname) ) {
             /* should never happen */
-            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unlink %s failed", tmpname);
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                             "unlink %s failed", tmpname);
+            goto x_fail;
+        }
 
         if ( libxl_write_exactly(ctx, autopass_fd, vnc_pass, strlen(vnc_pass),
-                                    tmpname, "vnc password") ) {
-            do { close(autopass_fd); } while(errno == EINTR);
-            goto skip_autopass;
+                                    tmpname, "vnc password") )
+            goto x_fail;
+
+        if ( lseek(autopass_fd, SEEK_SET, 0) ) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                             "rewind %s (autopass) failed", tmpname);
+            goto x_fail; 
         }
 
         args[2] = "-autopass";
     }
 
-skip_autopass:
     libxl__exec(autopass_fd, -1, -1, args[0], args);
     abort();
+
+ x_fail:
+    libxl__free_all(&gc);
+    return ERROR_FAIL;
 }
 
 /******************************************************************************/